package org.farming.plants;
/**
 * Flower, Plant class
 * @author DEADBEEF
 * @version 0.01a
 * @note Scarecrow will require a special case (can use any type of spear, and will be returned same type used on removal)
 * @note Needs to collect/check rest of interact strings
**/
public class Flowers extends Plants
{
    public static enum Flower implements Plants.PlantEnum {
      UNKNOWN     ( -3, "Unknown",    0,  0, 0,     "Unknown",         0,    "Unknown",       "",               false ), 
      NONE        ( -2, "None",       0,  0, 0,     "None",            0,    "None",          "Flower Patch",   false ), 
      WEEDS       ( -1, "Weeds",      0,  0, 0,     "Weeds",           6055, "Weeds",         "Flower Patch",   false ), 
      EMPTY       ( 0,  "Empty",      0,  0, 0,     "Empty",           0,    "Empty",         "Flower Patch",   false ), 
      MARIGOLD    ( 1,  "Marigold",   2,  5, 5096,  "Marigold seed",   6010, "Marigolds",     "",               true  ), 
      ROSEMARY    ( 2,  "Rosemary",   11, 5, 5097,  "Rosemary seed",   6014, "Rosemary",      "",               true  ), 
      NASTURTIUM  ( 3,  "Nasturtium", 24, 5, 5098,  "Nasturtium seed", 6012, "Nasturtiums",   "",               true  ), 
      WOAD        ( 4,  "Woad Leaf",  25, 5, 5099,  "Woad seed",       1793, "Woad leaf",     "Woad plant",     false ),
      LIMPWURT    ( 5,  "Limpwurt",   26, 5, 5100,  "Limpwurt seed",   225,  "Limpwurt root", "Limpwurt plant", true  ),
      SCARECROW   ( 6,  "Scarecrow",  23, 4, 6059,  "Scarecrow",       0,    "",              "",               true  ),//Need to get details to do special case
      WHITE_LILY  ( 7,  "White Lily", 52, 5, 14589, "White lily seed", 592,  "Ashes",         "Lily",           true  );
      
        private final int id, level, stages, seedId, itemId;   
        private final String seedString, itemString, interactString, name; 
        private final boolean canNote; 

        /**
         * Flower Enum
         * Interface params
         * @param id Our unique id and offset for the plant
         * @param name The reference for this plant which we can display to the user
         * @param level The farming level required to plant
         * @param stages How many growth stages the plant has (from first planted to harvestable inclusive)
         * @param seedId, Item id of the seed
         * @param seedString, Item string of the seed
         * @param itemId, Item id of the harvested plant
         * @param itemString, Item string of the harvested plant
         * @param interactString, String of the plant when grown
         * @param canNote, Whether the leprechaun can note this plant (noted item id's are +1 of the regular id)
         * Local params
        **/
        Flower(
            int id, 
            String name,
            int level, 
            int stages, 
            int seedId, 
            String seedString, 
            int itemId, 
            String itemString, 
            String interactString, 
            boolean canNote
        ) {
            this.id              = id;
            this.name            = name;
            this.level           = level;
            this.stages          = stages;
            this.seedId          = seedId;
            this.itemId          = itemId;
            this.seedString      = seedString;
            this.itemString      = itemString;
            this.interactString  = interactString;
            this.canNote         = canNote;
        }
        
        //Interface methods
        public int id()                 {return id;}
        public int level()              {return level;}
        public int stages()             {return stages;}
        public int seedId()             {return seedId;}
        public int itemId()             {return itemId;}
        public String seedString()      {return seedString;}
        public String itemString()      {return itemString;}
        public String interactString()  {return interactString;}
        public boolean canNote()        {return canNote;}
        public int noteId()             {return canNote?(itemId+1):itemId;}
        public String toString()        {return name;}
        //Local methods
    }

   /**
    * This was designed to be a static method, however static and abstract don't mix so this will have to do
    * 
    * @param bits The byte for the herb patch we want the state for
    * @return The calculated state enum
   **/
    public State getState(int bits)
    {
        bits = bits&255;//Cleanse
        int stateBits = (bits&192)>>6;//Get 7&8th bits
        int plantBits = bits&63;//Clear 7&8th bits
        if(stateBits==0x00){
            Flower p = getPlant(bits);
            if(getStagePlant(p,plantBits)==p.stages()){ return State.READY;
            }else{                                      return State.GROWING;}
      }else if(stateBits==0x01){                        return State.WATERED;
      }else if(stateBits==0x02){                        return State.DISEASED;
      }else if(stateBits==0x03){                        return State.DEAD;
      }else{                                            return State.UNKNOWN;}
   }
   
   /**
    * This was designed to be a static method, however static and abstract don't mix so this will have to do
    * 
    * @param bits The byte for the herb patch we want the plant for
    * @return The calculated plant enum
   **/
    public Flower getPlant(int bits)
    {
        bits = bits&255;//Cleanse
        int stateBits = (bits&192)>>6;//Get 7&8th bits
        int plantBits = bits&63;//Clear 7&8th bits
        if(bits>=0xAA&&bits<=0xAC){                                     return Flower.NONE;//Dead, can't id plant
        }else if((stateBits==0)&&((plantBits==0x03))){                  return Flower.EMPTY;
        }else if((stateBits==0)&&(plantBits>=0x00)&&(plantBits<=0x02)){ return Flower.WEEDS;
        }else if((plantBits>=0x08)&&(plantBits<=0x0C)){                 return Flower.MARIGOLD;
        }else if((plantBits>=0x0D)&&(plantBits<=0x11)){                 return Flower.ROSEMARY;
        }else if((plantBits>=0x12)&&(plantBits<=0x16)){                 return Flower.NASTURTIUM;
        }else if((plantBits>=0x17)&&(plantBits<=0x1B)){                 return Flower.WOAD;
        }else if((plantBits>=0x1C)&&(plantBits<=0x20)){                 return Flower.LIMPWURT;
        }else if((plantBits>=0x21)&&(plantBits<=0x24)){                 return Flower.SCARECROW;
        }else if((plantBits>=0x25)&&(plantBits<=0x29)){                 return Flower.WHITE_LILY;
        }else{                                                          return Flower.UNKNOWN;}
    }
   
   /**
    * This was designed to be a static method, however static and abstract don't mix so this will have to do
    * 
    * @param bits The byte for the herb patch we want the stage for
    * @return The calculated stage
   **/
    public int getStage(int bits)
    {
        bits = bits&255;//Cleanse
        int plantBits = bits&63;//Clear 7&8th bits
        return getStagePlant(getPlant(bits), plantBits);
    }
    private int getStagePlant(Flower plant, int plantBits)
    {
        switch(plant)
        {
            case EMPTY:
            case WEEDS:
            case UNKNOWN:
                return 0;
            case WHITE_LILY:
                plantBits++;//Increment plantbits by 1, scarecrow has only 4 stages
            default:
                return plantBits-(5*plant.id())-2;
        }
    }
}
/*
## Flower
format: sspp ppp
- plant types and growth states (p bits):
-- 0x00 - 0x03: layers of weeds removed (0x00 meaning no weeds removed, 0x03 meaning all weeds removed), iff both state bits are 0
-- 0x08 - 0x0c: marigold
-- 0x0d - 0x11: rosemary
-- 0x12 - 0x16: nasturtium
-- 0x17 - 0x1b: woad plant
-- 0x1c - 0x20: limpwurt plant
-- 0x21 - 0x24: scarecrow
-- 0x25 - 0x29: lily
- states (s bits):
-- 0x00: growing
-- 0x01: watered
-- 0x02: diseased
-- 0x03: dead

locations:
- falador, bits 0-7 of 508
- catherby, bits 8-15 of 508
- ardougne, bits 16-23 of 508
- port phasmatys, bits 24-31 of 508
*/